{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting MNIST_data\\train-images-idx3-ubyte.gz\n",
      "Extracting MNIST_data\\train-labels-idx1-ubyte.gz\n",
      "Extracting MNIST_data\\t10k-images-idx3-ubyte.gz\n",
      "Extracting MNIST_data\\t10k-labels-idx1-ubyte.gz\n",
      "第 0 次 0.08\n",
      "第 1 次 0.1\n",
      "第 2 次 0.14\n",
      "第 3 次 0.08\n",
      "第 4 次 0.22\n",
      "第 5 次 0.24\n",
      "第 6 次 0.28\n",
      "第 7 次 0.24\n",
      "第 8 次 0.26\n",
      "第 9 次 0.24\n",
      "第 10 次 0.2\n",
      "第 11 次 0.28\n",
      "第 12 次 0.28\n",
      "第 13 次 0.38\n",
      "第 14 次 0.28\n",
      "第 15 次 0.38\n",
      "第 16 次 0.42\n",
      "第 17 次 0.44\n",
      "第 18 次 0.52\n",
      "第 19 次 0.34\n",
      "第 20 次 0.24\n",
      "第 21 次 0.54\n",
      "第 22 次 0.54\n",
      "第 23 次 0.42\n",
      "第 24 次 0.54\n",
      "第 25 次 0.48\n",
      "第 26 次 0.56\n",
      "第 27 次 0.68\n",
      "第 28 次 0.52\n",
      "第 29 次 0.68\n",
      "第 30 次 0.66\n",
      "第 31 次 0.74\n",
      "第 32 次 0.58\n",
      "第 33 次 0.6\n",
      "第 34 次 0.64\n",
      "第 35 次 0.6\n",
      "第 36 次 0.7\n",
      "第 37 次 0.62\n",
      "第 38 次 0.64\n",
      "第 39 次 0.78\n",
      "第 40 次 0.6\n",
      "第 41 次 0.58\n",
      "第 42 次 0.7\n",
      "第 43 次 0.82\n",
      "第 44 次 0.78\n",
      "第 45 次 0.76\n",
      "第 46 次 0.76\n",
      "第 47 次 0.64\n",
      "第 48 次 0.76\n",
      "第 49 次 0.62\n",
      "第 50 次 0.78\n",
      "第 51 次 0.66\n",
      "第 52 次 0.78\n",
      "第 53 次 0.62\n",
      "第 54 次 0.74\n",
      "第 55 次 0.82\n",
      "第 56 次 0.8\n",
      "第 57 次 0.64\n",
      "第 58 次 0.72\n",
      "第 59 次 0.7\n",
      "第 60 次 0.78\n",
      "第 61 次 0.68\n",
      "第 62 次 0.76\n",
      "第 63 次 0.82\n",
      "第 64 次 0.84\n",
      "第 65 次 0.78\n",
      "第 66 次 0.86\n",
      "第 67 次 0.84\n",
      "第 68 次 0.82\n",
      "第 69 次 0.82\n",
      "第 70 次 0.78\n",
      "第 71 次 0.82\n",
      "第 72 次 0.72\n",
      "第 73 次 0.8\n",
      "第 74 次 0.78\n",
      "第 75 次 0.66\n",
      "第 76 次 0.8\n",
      "第 77 次 0.82\n",
      "第 78 次 0.76\n",
      "第 79 次 0.68\n",
      "第 80 次 0.82\n",
      "第 81 次 0.72\n",
      "第 82 次 0.82\n",
      "第 83 次 0.82\n",
      "第 84 次 0.72\n",
      "第 85 次 0.78\n",
      "第 86 次 0.86\n",
      "第 87 次 0.82\n",
      "第 88 次 0.8\n",
      "第 89 次 0.84\n",
      "第 90 次 0.78\n",
      "第 91 次 0.86\n",
      "第 92 次 0.78\n",
      "第 93 次 0.7\n",
      "第 94 次 0.84\n",
      "第 95 次 0.82\n",
      "第 96 次 0.86\n",
      "第 97 次 0.92\n",
      "第 98 次 0.78\n",
      "第 99 次 0.82\n",
      "第 100 次 0.8\n",
      "第 101 次 0.8\n",
      "第 102 次 0.86\n",
      "第 103 次 0.86\n",
      "第 104 次 0.84\n",
      "第 105 次 0.78\n",
      "第 106 次 0.78\n",
      "第 107 次 0.9\n",
      "第 108 次 0.82\n",
      "第 109 次 0.84\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "\n",
    "# 1.准备数据 参数1：文件路径 参数2：oneHot 数组内有一个内容为1则其他全为0\n",
    "mnist = input_data.read_data_sets('MNIST_data',one_hot=True)\n",
    "imageInput = tf.placeholder(tf.float32,[None,784])\n",
    "labelInput = tf.placeholder(tf.float32,[None,10])\n",
    "trainSize = 500\n",
    "testSize = 50\n",
    "trainTimes = 110\n",
    "learnRate = 0.01\n",
    "# 2.卷积运算\n",
    "# 维度转换 n*784->m*28*28*1 2dim->4dim\n",
    "imageInputReshape = tf.reshape(imageInput,[-1,28,28,1])\n",
    "# 进行卷积运算：权重w0与偏移b\n",
    "# 实现正态分布的权重矩阵 参数1：维度(卷积内核：5*5 输出：32 输入;1) 参数2：方差\n",
    "w0 = tf.Variable(tf.truncated_normal([5,5,1,32],stddev = 0.1))\n",
    "b0 = tf.Variable(tf.constant(0.1,shape=[32]))\n",
    "# layer1:激励函数+卷积运算\n",
    "layer1 = tf.nn.relu(tf.nn.conv2d(imageInputReshape,w0,strides=(1,1,1,1),padding='SAME')+b0)\n",
    "# 池化层 降维：m*28*28*32 / 1*4*4*1 = m*7*7*32\n",
    "layer1_pool = tf.nn.max_pool(layer1,ksize=[1,4,4,1],strides=[1,4,4,1],padding='SAME')\n",
    "# layer2 out:softmax(激励函数+乘加运算) softmax一种回归计算 \n",
    "w1 = tf.Variable(tf.truncated_normal([7*7*32,1024],stddev=0.1))\n",
    "b1 = tf.Variable(tf.constant(0.1,shape=[1024]))\n",
    "# n*7*7*32 -> n*1568(7*7*32)\n",
    "h_reshape = tf.reshape(layer1_pool,[-1,7*7*32])\n",
    "# n*1568(7*7*32) x 1568(7*7*32)*1024 = n*1024\n",
    "h1 = tf.nn.relu(tf.matmul(h_reshape,w1)+b1)\n",
    "# softmax(n*1024 x 1024*10 = n*10)表示n张图片在0-9即这10个数字中分布的概率\n",
    "w2 = tf.Variable(tf.truncated_normal([1024,10],stddev=0.1))\n",
    "b2 = tf.Variable(tf.constant(0.1,shape=[10]))\n",
    "predict = tf.nn.softmax(tf.matmul(h1,w2)+b2)\n",
    "# 获得正确结果出现的概率 n*10的矩阵 此处的乘法不是矩阵乘法而是普通乘法\n",
    "pRight = labelInput*tf.log(predict)\n",
    "pRightSum = 0\n",
    "# 求每次测试100份数据的总正确概率\n",
    "for m in range(0,testSzie):\n",
    "    for n in range(0,10):\n",
    "        pRightSum = pRightSum + pRight[m,n]\n",
    "# 求均值。并通过取反使得满足概率越大误差越小的前提，然后采用梯度下降法\n",
    "loss = -1*pRightSum/testSize   \n",
    "# 训练\n",
    "train = tf.train.GradientDescentOptimizer(learnRate).minimize(loss)\n",
    "with tf.Session() as sess:\n",
    "    sess.run(tf.global_variables_initializer())\n",
    "    for i in range(trainTimes):\n",
    "        # 每次读取500张进行训练\n",
    "        images,labels = mnist.train.next_batch(trainSize)\n",
    "        sess.run(train,feed_dict={imageInput:images,labelInput:labels})\n",
    "        testImages,testLabels = mnist.test.next_batch(testSize)\n",
    "        predict_test = sess.run(predict,feed_dict={imageInput:testImages,labelInput:labels})\n",
    "        # 观察预测结果是是否等于真值\n",
    "        equal = tf.equal(tf.arg_max(predict_test,1),tf.arg_max(testLabels,1))\n",
    "        # 计算均值\n",
    "        equal_float = tf.reduce_mean(tf.cast(equal,tf.float32))\n",
    "        equal_reslut = sess.run(equal_float,feed_dict={imageInput:testImages,labelInput:testLabels})\n",
    "        print(\"第\",i,\"次\",equal_reslut)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
